package com.android.gpuimage;

import android.graphics.PointF;
import android.opengl.GLES20;

/**
 * Created by winn on 17/8/14.
 */

public class TwinEnLargerFilter extends GPUImageFilter {

    public static final String ENLARGER_FILTER_FRAGMENT_SHADER_SRC = "" +
            "varying highp vec2 textureCoordinate;\n" +
            "uniform sampler2D inputImageTexture;\n" +
            "uniform highp float aspectRatio;\n" +
            "uniform highp vec2 center;\n" +
            "uniform highp float radius;\n" +
            "uniform highp float scale;\n" +
            "uniform highp vec2 center2;\n" +
            "uniform highp float radius2;\n" +
            "uniform highp float scale2;\n" +
            "void main() {\n" +
            "  highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n" +
            "  highp float dist = distance(center, textureCoordinateToUse);\n" +
            "  highp float dist2 = distance(center2, textureCoordinateToUse);\n" +
            "  textureCoordinateToUse = textureCoordinate;\n" +
            "  if (dist < radius){\n" +
            "    textureCoordinateToUse -= center;\n" +
            "    highp float percent = 1.0 - ((radius - dist) / radius) * scale;\n" +
            "    percent = percent * percent;\n" +
            "    textureCoordinateToUse = textureCoordinateToUse * percent;\n" +
            "    textureCoordinateToUse += center;\n" +
            "  }\n" +
            "  if (dist2 < radius2){\n" +
            "    textureCoordinateToUse -= center2;\n" +
            "    highp float percent = 1.0 - ((radius2 - dist2) / radius2) * scale2;\n" +
            "    percent = percent * percent;\n" +
            "    textureCoordinateToUse = textureCoordinateToUse * percent;\n" +
            "    textureCoordinateToUse += center2;\n" +
            "  }\n" +
            "  gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse);\n" +
            "}";


    public static final String ENLARGER_FILTER_FRAGMENT_SHADER = "" +
            "fGt4c2NkbSpiY21ieip8b2k4Kn5vcn5/eG9JZWV4bmNka35vMQB/ZGNsZXhnKnlrZ3pmb3g4TipjZHp/fkNna21vXm9yfn94bzEAf2RjbGV4ZypiY21ieipsZmVrfipreXpvaX5Ya35jZTEAf2RjbGV4ZypiY21ieip8b2k4KmlvZH5veDEAf2RjbGV4ZypiY21ieipsZmVrfip4a25jf3kxAH9kY2xleGcqYmNtYnoqbGZla34qeWlrZm8xAHxlY24qZ2tjZCIjKnEAKipiY21ieip8b2k4Kn5vcn5/eG9JZWV4bmNka35vXmVfeW8qNyp8b2k4In5vcn5/eG9JZWV4bmNka35vJHImKiJ+b3J+f3hvSWVleG5jZGt+byRzKiAqa3l6b2l+WGt+Y2UqISo6JD8qJyo6JD8qICpreXpvaX5Ya35jZSMjMQAqKmJjbWJ6KmxmZWt+Km5jeX4qNypuY3l+a2RpbyJpb2R+b3gmKn5vcn5/eG9JZWV4bmNka35vXmVfeW8jMQAqKn5vcn5/eG9JZWV4bmNka35vXmVfeW8qNyp+b3J+f3hvSWVleG5jZGt+bzEAKipjbCoibmN5fio2KnhrbmN/eSNxACoqKip+b3J+f3hvSWVleG5jZGt+b15lX3lvKic3KmlvZH5veDEAKioqKmJjbWJ6KmxmZWt+KnpveGlvZH4qNyo7JDoqJyoiInhrbmN/eSonKm5jeX4jKiUqeGtuY395IyogKnlpa2ZvMQAqKioqem94aW9kfio3KnpveGlvZH4qICp6b3hpb2R+MQAqKioqfm9yfn94b0llZXhuY2Rrfm9eZV95byo3Kn5vcn5/eG9JZWV4bmNka35vXmVfeW8qICp6b3hpb2R+MQAqKioqfm9yfn94b0llZXhuY2Rrfm9eZV95byohNyppb2R+b3gxACoqdwAqKm1mVUx4a21JZWZleCo3Kn5vcn5/eG84TiJjZHp/fkNna21vXm9yfn94byYqfm9yfn94b0llZXhuY2Rrfm9eZV95byMxAHc=";

    private int mAspectRatioLocation;

    private int mScaleLocation;
    private int mRadiusLocation;
    private int mCenterLocation;

    private int mScaleLocation2;
    private int mRadiusLocation2;
    private int mCenterLocation2;

    private float mAspectRatio;

    private float mScale;
    private float mRadius;
    private PointF mCenter;

    private float mScale2;
    private float mRadius2;
    private PointF mCenter2;

    public TwinEnLargerFilter() {
        this(0.3f, 0.14f, new PointF(0.3f, 0.5f),
                0.3f, 0.14f, new PointF(0.7f, 0.5f));
    }

    public TwinEnLargerFilter(float scale, float radius, PointF center,
                              float scale2, float radius2, PointF center2) {
        super(NO_FILTER_VERTEX_SHADER, ENLARGER_FILTER_FRAGMENT_SHADER_SRC
                /*FilterTools.getDecryptString(ENLARGER_FILTER_FRAGMENT_SHADER)*/);
        mScale = scale;
        mRadius = radius;
        mCenter = center;

        mScale2 = scale2;
        mRadius2 = radius2;
        mCenter2 = center2;
    }

    public boolean isSupportIntensity() {
        return true;
    }

    public void onInit() {
        super.onInit();

        mAspectRatioLocation = GLES20.glGetUniformLocation(getProgram(), "aspectRatio");

        mScaleLocation = GLES20.glGetUniformLocation(getProgram(), "scale");
        mRadiusLocation = GLES20.glGetUniformLocation(getProgram(), "radius");
        mCenterLocation = GLES20.glGetUniformLocation(getProgram(), "center");

        mScaleLocation2 = GLES20.glGetUniformLocation(getProgram(), "scale2");
        mRadiusLocation2 = GLES20.glGetUniformLocation(getProgram(), "radius2");
        mCenterLocation2 = GLES20.glGetUniformLocation(getProgram(), "center2");

        setScale(mScale);
        setRadius(mRadius);
        setCenter(mCenter);

        setScale2(mScale2);
        setRadius2(mRadius2);
        setCenter2(mCenter2);
    }

    public void onInitialized() {
        super.onInitialized();
    }

    public void setAspectRatio(final float aspectRatio) {
        mAspectRatio = aspectRatio;
        setFloat(mAspectRatioLocation, mAspectRatio);
    }

    public void setScale(final float scale) {
        mScale = scale;
        setFloat(mScaleLocation, mScale);
    }

    public float getScale() {
        return mScale;
    }

    public void setRadius(final float radius) {
        mRadius = radius;
        setFloat(mRadiusLocation, mRadius);
    }

    public float getRadius() {
        return mRadius;
    }

    public void setCenter(final PointF center) {
        mCenter = center;
        setPoint(mCenterLocation, mCenter);
    }

    public PointF getCenter() {
        return mCenter;
    }

    public void setScale2(final float scale2) {
        mScale2 = scale2;
        setFloat(mScaleLocation2, mScale2);
    }

    public float getScale2() {
        return mScale2;
    }

    public void setRadius2(final float radius2) {
        mRadius2 = radius2;
        setFloat(mRadiusLocation2, mRadius2);
    }

    public float getRadius2() {
        return mRadius2;
    }

    public void setCenter2(final PointF center2) {
        mCenter2 = center2;
        setPoint(mCenterLocation2, mCenter2);
    }

    public PointF getCenter2() {
        return mCenter2;
    }

    @Override
    public void onOutputSizeChanged(int width, int height) {
        super.onOutputSizeChanged(width, height);
        mAspectRatio = (float) height / width;
        setAspectRatio(mAspectRatio);
    }

    @Override
    public void setIntensity(float intensity) {
        super.setIntensity(intensity);
        setRadius(intensity);
        setRadius2(intensity);
    }
}
